#include <string.h> 
#include <stdio.h> 
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>

#include <compat/deprecated.h> 

#include "BuffFifo.h"
#include "manage.h"
#include "mail.h"
#include "disp.h"
#include "key.h"

void processKeyInMsg(char key_code);
void DisplayDisableTime(char motion);

#define LAMP_POS_PORT PORTB
#define LAMP_POS_DIR  DDRB

const char cVersion[] = "\r\nLampControl 0.1\r\n";

unsigned char EEMEM EppromTimeOn[3] = {0,0,0};
unsigned char EEMEM EppromTimeOff[3] = {0,0,0};


#define TIME_MANAGE_INTERVAL 10 //10ms

#define TIME_MANAGE_TASK 10 //100ms
static volatile unsigned int time_manage; 
static volatile unsigned int time_manage_task;
#define TIME_SYS_UPDATE_10MS 1//10ms
#define TIME_SYS_UPDATE_600MS 60//10ms
#define TIME_SYS_UPDATE_1S 100 //10ms
#define TIME_SYS_UPDATE_10S 1000 //1000ms
#define TIME_SYS_UPDATE_60S 6000 //60s
static volatile unsigned int time_sys_update = TIME_SYS_UPDATE_1S;

#define INIT_TIME_BLACK_OUT_10MS 1 //10ms
#define INIT_TIME_BLACK_OUT_1S 100 //10ms
#define INIT_TIME_BLACK_OUT_10S 1000 //10000 ms
static volatile unsigned int time_black_out = INIT_TIME_BLACK_OUT_10S; 

#define INIT_TIME_LAMP 30 //300ms
static volatile unsigned char time_lamp_control = INIT_TIME_LAMP;

#define INIT_TIME_SLEEP 15 //150ms
#define INIT_TIME_SLEEP_1S 100 //10s
#define INIT_TIME_SLEEP_10S 1000 //10s
static volatile unsigned int time_sleep_control = INIT_TIME_SLEEP_10S;


								/*D0,D1,D2,D3,           D4,Toggle post,time toggle mode,power save mode,display time*/
//unsigned char ucDispSigment[] = {  0, 0, 0, 0,SEGMENT_COLON,       0xff,               0,FALSE          ,0};

#define DISP_DEFAULT {  0, 0, 0, 0,SEGMENT_COLON,       0xff,               0,FALSE          ,0}

#define DISP_SEGMEN_BUFF_MAX 5
#define DISP_SEGMEN_DIGIT_MAX 9
struct 
{
	unsigned char ready;
	char seg[SEGMENT_DIGIT_MAX];
	unsigned char opt;	
	unsigned char t_mode;	
	unsigned char pwr;		
	unsigned char d_time;		
}
sDispSigment[DISP_SEGMEN_BUFF_MAX];

unsigned char ucTimeCurr[3]   = {1,0,0};
unsigned char ucTimeOn[3] 	  = {1,18,00};
unsigned char ucTimeOff[3] 	  = {0,06,00};

#define MANAGE_SERIAL_BUFF 30
BUFF_DECL_FIFO(ManageSerialMsgBuf,MANAGE_SERIAL_BUFF);


#define MANAGE_KEY_BUFF 5
BUFF_DECL_FIFO(ManageKeyMsgBuf,MANAGE_KEY_BUFF);


#define MANAGE_COMMAND_BUFF 30
BUFF_DECL_FIFO(ManageCommandMsgBuf,MANAGE_COMMAND_BUFF); 


void ManageSerialMsgSend(char *ptr, unsigned char size)
{
	unsigned char i;
	
	for(i=0;i<size;i++)
	{
		if( BuffPutFifo(ManageSerialMsgBuf,*ptr++) == FIFO_ERR)
		{
			break;
		}
	}
	if( SendMailFifo(SERIAL_DEV,0x01,size,(char *)ManageSerialMsgBuf) == FALSE )
	{
		while(TRUE);
	}
	
}


void ManageKeyInMsgSend(unsigned char command)
{

	if( BuffPutFifo(ManageKeyMsgBuf,command) == FIFO_ERR)
	{
		return;
	}

	if( SendMailFifo(KEYIN_DEV,0x01,1,(char *)ManageKeyMsgBuf) == FALSE)
	{
		while(TRUE);
	}
	
}


unsigned char command_power_save = FALSE;
unsigned char command_lamp_on = FALSE;
void InitManage( void )
{		
	unsigned char loop;
	
	LAMP_POS_PORT &= ~_BV(5); //set pin to low
	LAMP_POS_DIR  |= _BV(5);  //Output mode

	sbi(DDRD,PIN7);
	sbi(PORTD,PIN7);
	
	time_manage = TIME_MANAGE_INTERVAL;
	time_manage_task = TIME_MANAGE_TASK;
	
	BUFF_INIT_FIFO(ManageSerialMsgBuf);
	
	BUFF_INIT_FIFO(ManageKeyMsgBuf);

	BUFF_INIT_FIFO(ManageCommandMsgBuf);
	
	//ManageSerialMsgSend((char *)&cVersion,sizeof(cVersion));
	
	BuffPutFifo(ManageCommandMsgBuf,0x00); 
	BuffPutFifo(ManageCommandMsgBuf,0x01); 
	BuffPutFifo(ManageCommandMsgBuf,0x02); 

	
	for(loop=0;loop<DISP_SEGMEN_BUFF_MAX;loop++)
	{
		memset((void *)&sDispSigment[loop],0x00,sizeof(sDispSigment[loop]));
		sDispSigment[loop].ready = TRUE;
	}
	
	command_power_save = FALSE;
	
}


void TimeManage( void )
{
	if(time_manage > 0)
	{
		time_manage--;
		if(time_manage==0)
		{		
			if(time_manage_task>0)
			{
				time_manage_task--;
			}
			
			if(time_sys_update>0)
			{
				time_sys_update--;
			}
			
			if(time_black_out>0)
			{
				time_black_out--;
			}
			
			if(time_lamp_control>0)
			{
				time_lamp_control--;
			}
			
			if(time_sleep_control>0)
			{
				time_sleep_control--;
			}
			
			
			time_manage = TIME_MANAGE_INTERVAL;
		}
	}
}

unsigned char current_operation_mode = 0;
unsigned char command_edit_mode = FALSE;
void ManageMail(unsigned char act, unsigned char size, char * pbuf)
{
	signed char i;
	char c;
	
	if(act == 0x01) //RTC dev msg
	{	
		for(i=0;i<size;i++)
		{
			c = BuffPullFifo((psBufFifo)pbuf);			
			if( c != FIFO_ERR && (!!(command_edit_mode == TRUE && current_operation_mode==0) == FALSE))
			{			
				ucTimeCurr[0] = 1;
				ucTimeCurr[i+1] = c;
			}
		}  
	}
	else if(act == 0x02) //Key In dev msg
	{
		c = BuffPullFifo((psBufFifo)pbuf);
		if( c != FIFO_ERR)
		{					
			time_black_out = INIT_TIME_BLACK_OUT_10S;
			if(command_power_save==TRUE)
			{
				command_power_save = FALSE;				
				BuffPutFifo(ManageCommandMsgBuf,0x15); //turn display on
				BuffPutFifo(ManageCommandMsgBuf,0x72); //send power save off message to key
				MailSetToSleepMode(FALSE);
			}
			else
			{
				processKeyInMsg(c);
			}
		}
	}
}

char c_str[32];						
void ShowVersionToSerial(void)
{
	ManageSerialMsgSend((char *)&cVersion,sizeof(cVersion));
}

void ShowEppTimeOnToSerial(void)
{
	unsigned char time[3];	
	eeprom_read_block(( void *)&time , ( const void *)&EppromTimeOn , 3) ;	
	if( time[1] > 23 || time[2] > 59)
	{
		memset((void *)&time,0x00,3);
	}
	sprintf((char *)&c_str,"TimeOn %d,%d,%d\r\n",time[0],time[1],time[2]);	
	ManageSerialMsgSend((char *)&c_str,strlen(c_str));		
	memcpy((void *)&ucTimeOn, (const void *)&time, 3);
}

void ShowEppTimeOffToSerial(void)
{
	unsigned char time[3];	
	eeprom_read_block (( void *)&time , ( const void *)&EppromTimeOff , 3) ;
	if( time[1] > 23 || time[2] > 59)
	{
		memset((void *)&time,0x00,3);
	}
	sprintf((char *)&c_str,"TimeOff %d,%d,%d\r\n",time[0],time[1],time[2]);	
	ManageSerialMsgSend((char *)&c_str,strlen(c_str));		
	memcpy((void *)&ucTimeOff, (const void *)&time, 3);
}						

void WriteEppromTimeOn(void)
{

	//eeprom_write_block (( const void *)&EppromTimeOn,( void *)&ucTimeOn , 3) ;
	eeprom_write_block (( const void *)&ucTimeOn ,( void *)&EppromTimeOn, 3) ;
	BuffPutFifo(ManageCommandMsgBuf,0x01); 
}

void WriteEppromTimeOff(void)
{

	//eeprom_write_block (( const void *)&EppromTimeOff,( void *)&ucTimeOff , 3);
	eeprom_write_block (( const void *)&ucTimeOff ,( void *)&EppromTimeOff, 3);
	BuffPutFifo(ManageCommandMsgBuf,0x02); 
}

void SetLampToON(void)
{
	LAMP_POS_PORT |= _BV(5); //set pin to high
	command_lamp_on = TRUE;
	BuffPutFifo(ManageCommandMsgBuf,0x15); 
}

void SetLampToOff(void)
{
	LAMP_POS_PORT &= ~_BV(5); //set pin to low
	command_lamp_on = FALSE;
	BuffPutFifo(ManageCommandMsgBuf,0x15);
}


void SetSleepMode(void)
{
	//cbi(PORTD,PIN7);
	set_sleep_mode(SLEEP_MODE_PWR_SAVE);		
	//set_sleep_mode(SLEEP_MODE_PWR_DOWN);		
	sleep_enable();
	sleep_cpu();
	sleep_disable();		
	time_sleep_control = INIT_TIME_SLEEP;
	//BuffPutFifo(ManageCommandMsgBuf,0x32); //request current time 
	//sbi(PORTD,PIN7);
}

unsigned char command_update = FALSE;
unsigned char ucDispPostSigmentToggle=4;
unsigned char previce_key = KEY_OFF;
void processKeyInMsg(char key_code)
{
	//if(key_code==KEY_DOWN_0 && previce_key != KEY_HOLD_0)
	if(key_code==KEY_DOWN_0 && previce_key == KEY_UP_0)
	{
		if(command_edit_mode == FALSE)
		{
			if(current_operation_mode == 0) 
			{
				current_operation_mode = 1;
				time_sys_update = TIME_SYS_UPDATE_10S;
				command_update = TRUE;
				ucDispPostSigmentToggle = 0xff;
				BuffFlushFifo(ManageCommandMsgBuf);	//stop all command
				BuffPutFifo(ManageCommandMsgBuf,0x13); //Display ON
				BuffPutFifo(ManageCommandMsgBuf,0x11); //display time on 
			}
			else if(current_operation_mode == 1) 
			{
				current_operation_mode = 2;
				time_sys_update = TIME_SYS_UPDATE_10S;
				command_update = TRUE;
				ucDispPostSigmentToggle = 0xff;
				BuffFlushFifo(ManageCommandMsgBuf);	//stop all command
				BuffPutFifo(ManageCommandMsgBuf,0x14); //Display ON
				BuffPutFifo(ManageCommandMsgBuf,0x12); //display time off
			}
			else if(current_operation_mode == 2) 
			{
				current_operation_mode = 0;
				time_sys_update = TIME_SYS_UPDATE_10S;
				command_update = TRUE;
				ucDispPostSigmentToggle = 4;
				BuffFlushFifo(ManageCommandMsgBuf);	//stop all command
				BuffPutFifo(ManageCommandMsgBuf,0x17); //Display STR Curr
				BuffPutFifo(ManageCommandMsgBuf,0x16); //display current time
			}
		}
		else
		{
			ucDispPostSigmentToggle++;
			if(ucDispPostSigmentToggle > 3)
			{
				ucDispPostSigmentToggle = 0;
			}
			command_update = TRUE;
			time_sys_update = TIME_SYS_UPDATE_10S;
			BuffPutFifo(ManageCommandMsgBuf,0x15); 			
			
			sprintf((char *)&c_str,"toggle %d\r\n",ucDispPostSigmentToggle);
			ManageSerialMsgSend((char *)&c_str,strlen(c_str));		
			
		}
	}
	//else if(key_code==KEY_HOLD_0)
	else if(key_code==KEY_HOLD_0 && previce_key == KEY_UP_0)
	{
		if(command_edit_mode == TRUE)
		{
			ucDispPostSigmentToggle = 0xff;
			if(current_operation_mode == 2) 
			{
				BuffPutFifo(ManageCommandMsgBuf,0x12); //display time off
				BuffPutFifo(ManageCommandMsgBuf,0x42); //display current time			
			}
			else if(current_operation_mode == 1) 
			{
				BuffPutFifo(ManageCommandMsgBuf,0x11); //display time on
				BuffPutFifo(ManageCommandMsgBuf,0x41); //display current time							
			}
			else
			{
				BuffPutFifo(ManageCommandMsgBuf,0x31); 						
				BuffPutFifo(ManageCommandMsgBuf,0x16); //display current time			
				ucDispPostSigmentToggle = 4;
			}
			command_update = TRUE;
			time_sys_update = TIME_SYS_UPDATE_10S;
			command_edit_mode = FALSE;
		}
		else
		{ 
			ucDispPostSigmentToggle = 0;
			command_update = TRUE;
			command_edit_mode = TRUE;
			time_sys_update = TIME_SYS_UPDATE_10S;
			BuffPutFifo(ManageCommandMsgBuf,0x15); 		
		}
	}
	//else if(key_code==KEY_DOWN_1)
	else if(key_code==KEY_DOWN_1 && previce_key == KEY_UP_1)
	{
		if(command_edit_mode == TRUE)
		{
			command_update = TRUE;
			time_sys_update = TIME_SYS_UPDATE_10S;
			BuffPutFifo(ManageCommandMsgBuf,0x21); //Increate time in position 
		}
	}
	//else if(key_code==KEY_DOWN_2)
	else if(key_code==KEY_DOWN_2 && previce_key==KEY_UP_2)
	{
		if(command_edit_mode == TRUE)
		{
			command_update = TRUE;
			time_sys_update = TIME_SYS_UPDATE_10S;
			BuffPutFifo(ManageCommandMsgBuf,0x22); //Decreate time in position 
		}
	}	
	previce_key = key_code;
}

// void SendMailToDisp(char reset, char motion, unsigned char time, char * ptr, unsigned char size)
// {
// //	unsigned char loop;
	// //int status;
	// char act;
	
	// *(ptr + 5) = ucDispPostSigmentToggle;
	// *(ptr + 6) = command_edit_mode;
	// *(ptr + 7) = 0;
	// if(command_power_save == TRUE)
	// {
		// *(ptr + 7) |= 0x01;
	// }
	
	// if(command_lamp_on == TRUE)
	// {
		// *(ptr + 7) |= 0x10;
	// }
		
	// *(ptr + 8) = time;		
	
	// if(motion == TRUE)
	// {
		// act = 0x02;
	// }
	// else
	// {
		// act = 0x01;
	// }
	
	// if(reset == TRUE)
	// {
		// act |= 0x80;
	// }
	
	// if( SendMailFifo(DISP_DEV,act,size,ptr) == FALSE)
	// {
		// while(TRUE);
	// }
// }


void SendMailBufferToDisp(char act, char reset, unsigned char time, char * ptr)
{
	unsigned char pos;
	
	for(pos=0;pos<DISP_SEGMEN_BUFF_MAX;pos++)
	{
		if( sDispSigment[pos].ready == TRUE )
		{
			sDispSigment[pos].ready = FALSE;			

			if( ptr != 0)
			{
				memcpy((void *)&sDispSigment[pos].seg, (const void *)ptr, SEGMENT_DIGIT_MAX);		
			}
			
			sDispSigment[pos].opt = ucDispPostSigmentToggle;	
			sDispSigment[pos].t_mode = command_edit_mode;	
			sDispSigment[pos].pwr = 0;		
			if(command_power_save == TRUE)
			{
				sDispSigment[pos].pwr |= 0x01;
			}
			if(command_lamp_on == TRUE)
			{
				sDispSigment[pos].pwr |= 0x10;
			}			
			sDispSigment[pos].d_time = time;								
			if(reset == TRUE)
			{
				act |= 0x80;
			}			
			break;
		}
		
	}

	if(pos < DISP_SEGMEN_BUFF_MAX )
	{
		if( SendMailFifo(DISP_DEV,act,sizeof(sDispSigment[pos]),(char *)&sDispSigment[pos]) == FALSE)
		{
			while(TRUE);
		}		
	}
	else
		while(TRUE);
	
}

 

void DisplayTime(char * ptr,char motion)
{
	// unsigned char i;
	
	// for(i=0;i<2;i++)
	// {
		// ucDispSigment[(i*2)+1] = *ptr % 10;
		// ucDispSigment[(i*2)+0] = *ptr / 10;			
		// ptr++;
	// }

	// ucDispSigment[4] = SEGMENT_COLON;
	
	// SendMailToDisp(FALSE,motion,0,(char *)&ucDispSigment,sizeof(ucDispSigment));
	
	unsigned char DispSegment[SEGMENT_DIGIT_MAX];
	char act = 0x01;	
	unsigned char i;
	
	for(i=0;i<2;i++)
	{
		DispSegment[(i*2)+1] = *ptr % 10;
		DispSegment[(i*2)+0] = *ptr / 10;			
		ptr++;
	}

	DispSegment[4] = SEGMENT_COLON;	
	
	if( motion == TRUE )
	{
		act = 0x02;
	}		
	SendMailBufferToDisp(act, FALSE, 0, (char *)&DispSegment);		
	
}


void DisplayCurrentTime(char motion)
{
	if(ucTimeCurr[0] == 1)
	{
		DisplayTime((char *)&ucTimeCurr[1],motion);		
	}
}


void DisplayTimeOn(void)
{
	char motion = TRUE;
	
	if( command_edit_mode==TRUE )
	{
		motion = FALSE;
	}

	if(ucTimeOn[0] == 0)
	{
		DisplayDisableTime(motion);
	}
	else
	{
		DisplayTime((char *)&ucTimeOn[1],motion);
	}
}

void DisplayTimeOff(void)
{
	char motion = TRUE;
	
	if( command_edit_mode==TRUE )
	{
		motion = FALSE;
	}
	
	if(ucTimeOff[0] == 0)
	{
		DisplayDisableTime(motion);
	}
	else
	{
		DisplayTime((char *)&ucTimeOff[1],motion);
	}
}

const char DisplaySegmentDisableTime[SEGMENT_DIGIT_MAX] = {SEGMENT_DAT,SEGMENT_DAT,SEGMENT_DAT,SEGMENT_DAT,SEGMENT_COLON};
void DisplayDisableTime(char motion)
{
	// memcpy((void *)&ucDispSigment, (const void *)&DisplaySegmentDisableTime, SEGMENT_DIGIT_MAX);
	
	// SendMailToDisp(FALSE,motion,0,(char *)&ucDispSigment,sizeof(ucDispSigment));	
	
	char act = 0x01;	
	if( motion == TRUE )
	{
		act = 0x02;
	}
	SendMailBufferToDisp(act, FALSE, 0, (char *)&DisplaySegmentDisableTime);			
}

const char DisplaySegmentON[SEGMENT_DIGIT_MAX] = {SEGMENT_O,SEGMENT_N,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF};
void DisplayStrON(char motion)
{
	// memcpy((void *)&ucDispSigment, (const void *)&DisplaySegmentON, SEGMENT_DIGIT_MAX);
	
	// SendMailToDisp(TRUE,motion,100,(char *)&ucDispSigment,sizeof(ucDispSigment));
	
	char act = 0x01;	
	if( motion == TRUE )
	{
		act = 0x02;
	}
	SendMailBufferToDisp(act, TRUE, 15, (char *)&DisplaySegmentON);		
}

const char DisplaySegmentOFF[SEGMENT_DIGIT_MAX] = {SEGMENT_O,SEGMENT_F,SEGMENT_F,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF};
void DisplayStrOFF(char motion)
{
	// memcpy((void *)&ucDispSigment, (const void *)&DisplaySegmentOFF, SEGMENT_DIGIT_MAX);
	
	// SendMailToDisp(TRUE,motion,100,(char *)&ucDispSigment,sizeof(ucDispSigment));
	
	char act = 0x01;	
	if( motion == TRUE )
	{
		act = 0x02;
	}
	SendMailBufferToDisp(act, TRUE, 15, (char *)&DisplaySegmentOFF);	
}

const char DisplaySegmentCurr[SEGMENT_DIGIT_MAX] = {SEGMENT_C,SEGMENT_U,SEGMENT_R,SEGMENT_R,SEGMENT_ALL_OFF};
void DisplayStrCurr(char motion)
{
	// memcpy((void *)&ucDispSigment, (const void *)&DisplaySegmentCurr, SEGMENT_DIGIT_MAX);
	
	// SendMailToDisp(FALSE,motion,0,(char *)&ucDispSigment,sizeof(ucDispSigment));
		
	char act = 0x01;	
	if( motion == TRUE )
	{
		act = 0x02;
	}
	SendMailBufferToDisp(act, TRUE, 15, (char *)&DisplaySegmentCurr);
}


void DisplayOptionUpdate(void)
{	
	// ucDispSigment[5] = ucDispPostSigmentToggle;
	// ucDispSigment[6] = command_edit_mode;
	// ucDispSigment[7] = 0;		

	// if(command_power_save == TRUE)
	// {
		// ucDispSigment[7] |= 0x01;
	// }
	
	// if(command_lamp_on == TRUE)
	// {
		// ucDispSigment[7] |= 0x10;
	// }	
	
	// ucDispSigment[8] = 0;		
	
	// if( SendMailFifo(DISP_DEV,0x03,sizeof(ucDispSigment),(char *)&ucDispSigment) == FALSE )
	// {
		// while(TRUE);
	// }
	
	SendMailBufferToDisp(0x03, FALSE, 0, (char *)0);
	
}

char SetIncreaseSegmentPost(char *pTime, unsigned char pos)
{
	unsigned char ucTh;
	unsigned char ucTl;
	
	if( pos==2 || pos==3)
	{
		ucTh = (*(pTime + 2) / 10);
		ucTl = (*(pTime + 2) % 10);
		if(pos==2)
		{
			ucTh++;
			if(ucTh > 5)
				ucTh = 0;
		}
		else if(pos==3)
		{
			ucTl++;
			if(ucTl > 9)
				ucTl = 0;
		}
		*(pTime + 2) = (ucTh * 10) + ucTl;
	}
	else if( pos==0 || pos==1)
	{
		ucTh = (*(pTime + 1) / 10);
		ucTl = (*(pTime + 1) % 10);
		if(pos==1)
		{
			ucTl++;
			if(ucTh > 1 && ucTl > 3)
				ucTl = 0;
			else if(ucTl > 9)
				ucTl = 0;
		}
		else if(pos==0)
		{
			ucTh++;
			if(ucTh > 1)
			{
				if(ucTh > 2)				
					ucTh = 0;
				
				if(ucTl > 3)
					ucTl = 3;
			}
		}
		*(pTime + 1) = (ucTh * 10) + ucTl;			
	}
	else
		return FALSE;
		
	return TRUE;
}

char SetIncreaseEnableDisable(char *pTime, unsigned char pos)
{
	char rest = TRUE;
	if(*(pTime+0) == 0)
	{
		*(pTime+0) = 1;				
		rest = SetIncreaseSegmentPost(pTime ,pos);
	}
	else if( (pos==0) && ((*(pTime+1) / 10) >= 2) )
	{
		*(pTime+0) = 0;				
	}
	else
	{
		rest = SetIncreaseSegmentPost(pTime ,pos);
	}
	return rest;
}

char SetDecreaseSegmentPost(char *pTime, unsigned char pos)
{	
	signed char ucTh;
	signed char ucTl;
		
	if( pos==2 || pos==3)
	{
		ucTh = (signed char)(*(pTime + 2) / 10);
		ucTl = (signed char)(*(pTime + 2) % 10);
		if(pos==2)
		{
			if(--ucTh < 0)
			{
				ucTh = 5;
			}
		}
		else if(pos==3)
		{
			if(--ucTl < 0)
			{
				ucTl = 9;
			}			
		}
		*(pTime + 2) = (ucTh * 10) + ucTl;
	}
	else if( pos==0 || pos==1)
	{
		ucTh = (*(pTime + 1) / 10);
		ucTl = (*(pTime + 1) % 10);
		if(pos==1)
		{
			ucTl--;
			if(ucTh > 1 && ucTl < 0)
			{
				ucTl = 3;
			}
			else if(ucTl < 0)
			{
				ucTl = 9;
			}
		}
		else if(pos==0)
		{
			ucTh--;
			if(ucTh < 0)
			{
				ucTh = 2;
				if(ucTl > 3)
				{
					ucTl = 3;
				}
			}
		}
		*(pTime + 1) = (ucTh * 10) + ucTl;			
	}
	else
		return FALSE;
		
	return TRUE;
}

char SetDecreaseEnableDisable(char *pTime, unsigned char pos)
{
	char rest = TRUE;
	if(*(pTime+0) == 0)
	{
		*(pTime+0) = 1;				
		rest = SetDecreaseSegmentPost(pTime ,pos);
	}
	else if( (pos==0) && ((*(pTime+1) / 10) == 0) )
	{
		*(pTime+0) = 0;				
	}
	else
	{
		rest = SetDecreaseSegmentPost(pTime ,pos);
	}
	
	return rest;
}


void IncreaseSegmentTime(void)
{
	if(ucDispPostSigmentToggle < (SEGMENT_DIGIT_MAX-1))
	{
		if( current_operation_mode == 2)
		{
			SetIncreaseEnableDisable((char *)&ucTimeOff ,ucDispPostSigmentToggle);
			// if(ucTimeOff[0] == 0)
			// {
				// ucTimeOff[0] = 1;				
				// SetIncreaseSegmentPost((char *)&ucTimeOff ,ucDispPostSigmentToggle);
			// }
			// else if( (ucDispPostSigmentToggle==0) && ((ucTimeOff[1] / 10) >= 2) )
			// {
				// ucTimeOff[0] = 0;				
			// }
			// else
			// {
				// SetIncreaseSegmentPost((char *)&ucTimeOff ,ucDispPostSigmentToggle);
			// }
			BuffPutFifo(ManageCommandMsgBuf,0x12); //display time off
		}
		else if( current_operation_mode == 1)
		{
			SetIncreaseEnableDisable((char *)&ucTimeOn ,ucDispPostSigmentToggle);
			//SetIncreaseSegmentPost((char *)&ucTimeOn ,ucDispPostSigmentToggle);
			BuffPutFifo(ManageCommandMsgBuf,0x11); //display time on
		}
		else if( current_operation_mode == 0)
		{
			SetIncreaseSegmentPost((char *)&ucTimeCurr ,ucDispPostSigmentToggle);
			BuffPutFifo(ManageCommandMsgBuf,0x10); //display current time 
		}
		command_update = TRUE;
		time_sys_update = TIME_SYS_UPDATE_10S;
	}
	
}

void DecreaseSegmentTime(void)
{
	if(ucDispPostSigmentToggle < (SEGMENT_DIGIT_MAX-1))
	{
		if( current_operation_mode == 2)
		{
			SetDecreaseEnableDisable((char *)&ucTimeOff ,ucDispPostSigmentToggle);
			//SetDecreaseSegmentPost((char *)&ucTimeOff ,ucDispPostSigmentToggle);
			BuffPutFifo(ManageCommandMsgBuf,0x12); //display time off
		}
		else if( current_operation_mode == 1)
		{
			SetDecreaseEnableDisable((char *)&ucTimeOn ,ucDispPostSigmentToggle);
			//SetDecreaseSegmentPost((char *)&ucTimeOn ,ucDispPostSigmentToggle);
			BuffPutFifo(ManageCommandMsgBuf,0x11); //display time on
		}
		else if( current_operation_mode == 0)
		{
			SetDecreaseSegmentPost((char *)&ucTimeCurr ,ucDispPostSigmentToggle);
			BuffPutFifo(ManageCommandMsgBuf,0x10); //display current time 
		}	
		command_update = TRUE;
		time_sys_update = TIME_SYS_UPDATE_10S;
	}

}


void SetTimeToRTC(void)
{	
	if( SendMailFifo(RTC_DEV,0x01,2,(char *)&ucTimeCurr[1]) == FALSE)
	{
		while(TRUE);
	}
	
}

void GetTimeFromRTC(void)
{
	if( SendMailFifo(RTC_DEV,0x02,0,(char *)0) == FALSE)
	{
		while(TRUE);
	}
}

void DisplayTimeUpdate(void)
{
	current_operation_mode = 0;
	if( command_power_save == TRUE )
	{
		time_sys_update = TIME_SYS_UPDATE_10S; //in sleep mode set time update to 10S
	}
	else
	{
		time_sys_update = TIME_SYS_UPDATE_60S;
	}
	previce_key = KEY_OFF;
	ucDispPostSigmentToggle = 4;
	if(command_edit_mode==TRUE)
	{
		command_edit_mode = FALSE;
		time_black_out = INIT_TIME_BLACK_OUT_10S;
		DisplayCurrentTime(TRUE);			
	}
	else
	{
		printf("\r%02d:%02d",ucTimeCurr[1],ucTimeCurr[2]);
		DisplayCurrentTime(FALSE);	
		
	}			
					
}

void ProcessBlackOut(void)
{
	if(command_edit_mode==FALSE)
	{
		if(command_power_save == FALSE)
		{
			command_power_save = TRUE;			
			BuffPutFifo(ManageCommandMsgBuf,0x15); 
			//enable key in interrup
			BuffPutFifo(ManageCommandMsgBuf,0x71);
			
			MailSetToSleepMode(TRUE);			
			
			time_sys_update = TIME_SYS_UPDATE_10S; //in sleep mode set time update to 10S
		}

		time_sleep_control = INIT_TIME_SLEEP_1S;
		
		//set to sleep
//		BuffPutFifo(ManageCommandMsgBuf,0x61);
	}
}

void ProcessLampControl(void)
{
	if( command_edit_mode == FALSE )
	{
		if(ucTimeOn[0]==1 && ucTimeOn[1]==ucTimeCurr[1] && ucTimeOn[2]==ucTimeCurr[2])
		{
			BuffPutFifo(ManageCommandMsgBuf,0x51); 
		}

		if(ucTimeOff[0]==1 && ucTimeOff[1]==ucTimeCurr[1] && ucTimeOff[2]==ucTimeCurr[2])
		{
			BuffPutFifo(ManageCommandMsgBuf,0x52); 
		}
	}
}

void processCommand(void)
{
	char command;
					
	if(BuffPeekFifo(ManageCommandMsgBuf) != FIFO_ERR)
	{
		command = BuffPullFifo(ManageCommandMsgBuf);
		if(command >= 0x00 && command < 0x10)
		{
			if(command == 0x00) 
			{
				ShowVersionToSerial();
			}			
			else if(command == 0x01) 
			{
				ShowEppTimeOnToSerial();
			}			
			else if(command == 0x02) 
			{
				ShowEppTimeOffToSerial();
			}						
		}
		else if(command >= 0x10 && command < 0x20)
		{
			if(command == 0x10) //Display current time
			{
				DisplayCurrentTime(FALSE);
			}
			else if(command == 0x11) //Display time on
			{
				DisplayTimeOn();
			}
			else if(command == 0x12) //Display time off
			{
				DisplayTimeOff();
			}
			else if(command == 0x13) //Display  LED time on
			{
				DisplayStrON(FALSE);
			}
			else if(command == 0x14) //Display LED time off
			{
				DisplayStrOFF(FALSE);
			}	
			else if(command == 0x15) //Display toggle 
			{
				DisplayOptionUpdate();
			}				
			else if(command == 0x16) //Display current time
			{
				DisplayCurrentTime(TRUE);
			}			
			else if(command == 0x17) //Display LED current time
			{
				DisplayStrCurr(FALSE);
			}			

		}
		else if(command >= 0x20 && command < 0x30)
		{
			if(command == 0x21)
			{
				IncreaseSegmentTime();
			}
			else if(command == 0x22)
			{
				DecreaseSegmentTime();
			}
		}
		else if(command >= 0x30 && command < 0x40)
		{
			if(command == 0x31)
			{
				SetTimeToRTC();
			}			
			else if(command == 0x32)
			{
				GetTimeFromRTC();
			}			
		}
		else if(command >= 0x40 && command < 0x50)
		{
			if(command == 0x41)
			{
				WriteEppromTimeOn();
			}			
			else if(command == 0x42)
			{
				WriteEppromTimeOff();
			}			
		}
		else if(command >= 0x50 && command < 0x60)
		{
			if(command == 0x51)
			{
				SetLampToON();
			}			
			else if(command == 0x52)
			{
				SetLampToOff();
			}			

		}
		else if(command >= 0x60 && command < 0x70)
		{
			if(command == 0x61)
			{
				SetSleepMode();
			}
		}
		else if(command >= 0x70 && command < 0x80)
		{
			if(command == 0x71)
			{
				ManageKeyInMsgSend(TRUE);
			}
			else if(command == 0x72)
			{
				ManageKeyInMsgSend(FALSE);
			}
		}
		
	}
}

void ManageTask( void )
{
	if(time_manage_task==0 || command_update==TRUE ||  command_power_save==TRUE)
	{
		time_manage_task = TIME_MANAGE_TASK;
		command_update = FALSE;
				
		processCommand();		
	}
	
	if(time_sys_update==0)
	{
		DisplayTimeUpdate();	
	}

	
	if(time_lamp_control==0)
	{	
		time_lamp_control = INIT_TIME_LAMP;
		ProcessLampControl();
	}

	if(time_black_out==0 && command_power_save==FALSE)
	{
		ProcessBlackOut();
	}

	
	if(time_sleep_control==0 && command_power_save==TRUE)
	{
		time_sleep_control = INIT_TIME_SLEEP;
		SetSleepMode();
	}
}
